package com.tool.grab.vpn.task;

import android.net.VpnService;

import com.tool.grab.Constant;
import com.tool.grab.vpn.header.IPPacket;
import com.tool.grab.vpn.header.TCPPacket;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

public class TCPTunnel implements TunnelEventListener{
    private SocketChannel channel;

    private IPPacket packet;
    private int localPort;
    private int remotePort;
    private String localIPString;
    private String remoteIPString;

    private int sendBytes;
    private int receiveBytes;

    public TCPTunnel(Selector selector, IPPacket packet) throws IOException {
        this.packet = packet;
        channel = SocketChannel.open();
        channel.configureBlocking(false);

        TCPPacket tcpPacket = new TCPPacket(packet.getBytes(),packet.getOffset() + packet.getHeaderLength(),packet.getValidLength());
        remotePort = tcpPacket.getRemotePort();
        remoteIPString = packet.getRemoteIpString();
        localPort = tcpPacket.getLocalPort();
        localIPString = packet.getLocalIpString();

        // 绑定到指定的IP地址和端口
        channel.socket().bind(new InetSocketAddress(localIPString,localPort));
        channel.register(selector,SelectionKey.OP_CONNECT | SelectionKey.OP_READ ,this);

    }



    public void connect(VpnService service) throws IOException{
        if(isOpen()){
            if(service.protect(channel.socket())){
                channel.connect(new InetSocketAddress(remoteIPString,remotePort));
            }
        }
    }




    @Override
    public void keyReady(SelectionKey key) throws IOException {
        if(key.isConnectable()){
            writePacket(packet);
        }else if(key.isReadable()){
            onRead();
        }
    }

    public void onRead()throws IOException{
        ByteBuffer buffer = ByteBuffer.allocate(Constant.MUTE_SIZE);
        int i = 0;
        int sum = 0;
        while (i != -1){
            i = channel.read(buffer);
            if(i > 0){
                sum += i;
            }
        }
        if(sum <= 0)return;
        receiveBytes += sum;

        //读取数据保存
        byte[] bytes = buffer.array();
        
    }

    public void writePacket(IPPacket packet) throws IOException{
        ByteBuffer buffer = ByteBuffer.wrap(packet.getBytes(),packet.getOffset(),packet.getValidLength());
        while (buffer.hasRemaining()){
            sendBytes += channel.write(buffer);
        }
    }

    public boolean isOpen(){
        return channel != null && channel.isOpen();
    }

    public boolean isRun() {
        return channel != null && channel.isConnected();
    }

    public int getSendBytes() {
        return sendBytes;
    }

    public void setSendBytes(int sendBytes) {
        this.sendBytes = sendBytes;
    }

    public int getReceiveBytes() {
        return receiveBytes;
    }

    public void setReceiveBytes(int receiveBytes) {
        this.receiveBytes = receiveBytes;
    }
}
